﻿using System;
using System.Collections.Generic;

namespace InDepth2Demo.Chapter3
{
    public class GenericMethod_3
    {
        // 泛型方法
        public T CreateInstance<T>() where T : new()
        {
            return new T();
        }

        public static List<T> MakeList<T>(T first, T second)
        {
            var list = new List<T>() { first, second };
            return list;
        }

        public static void Call()
        {
            List<string> strings = MakeList<string>("first", "second");
            foreach (string s in strings)
            {
                Console.WriteLine(s);
            }
        }

        static bool AreReferencesEqual<T>(T first, T second)
            where T : class
        {
            return first == second;
        }

        public static void Call2()
        {
            string name = "Joy";
            string intro1 = "My name is " + name;
            string intro2 = "My name is " + name;
            Console.WriteLine(intro1 == intro2);            // True
            Console.WriteLine(AreReferencesEqual(intro1, intro2));      // Flase
        }

        public static void Call3()
        {
            Pair<int, string> pair1 = new Pair<int, string>(10, "value");   // 泛型类不能简化 类型实参 <int, string>
            bool flag = pair1.Equals(new Pair<int, string>(5, "value"));
            Pair<int, string> pair2 = Pair.New(10, "value");                // 非泛型类 的 泛型方法 可以简化 类型实参 <int, string>
        }
    }

    // 表示一对值的泛型类
    public sealed class Pair<T1, T2> : IEquatable<Pair<T1, T2>>
    {
        private static readonly IEqualityComparer<T1> FirstComparer = EqualityComparer<T1>.Default;
        private static readonly IEqualityComparer<T2> SecondComparer = EqualityComparer<T2>.Default;

        private readonly T1 first;
        private readonly T2 second;

        public Pair(T1 first, T2 second)
        {
            this.first = first;
            this.second = second;
        }

        public T1 First { get { return first; } }

        public T2 Second { get { return second; } }

        public bool Equals(Pair<T1, T2> other)
        {
            return other != null &&
            FirstComparer.Equals(this.First, other.First) &&
            SecondComparer.Equals(this.Second, other.Second);
        }
        public override bool Equals(object obj)
        {
            return Equals(obj as Pair<T1, T2>);
        }
        public override int GetHashCode()
        {
            return FirstComparer.GetHashCode(first) * 37 +
                SecondComparer.GetHashCode(second);
        }
    }

    // 使用包含泛型方法的非泛型类型 进行类型推断
    public static class Pair
    {
        public static Pair<T1, T2> New<T1, T2>(T1 first, T2 second)
        {
            return new Pair<T1, T2>(first, second);
        }
    }

    //数值约束
    //class AddClass<T> where T : numeric
    //{ }
}
